import tkinter.ttk as ttk
import threading
from logging import warning
from links.abstract_link_ui import AbstractUiLink


class PageSettingsIO(ttk.Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.controller = None
        self.controller: AbstractUiLink
        self.open_btn = None
        self.page = None
        self.__check_io_interval = 0.05
        self.timer = None

    def init_ui(self, controller):
        row = 0
        title_font = ("TkDefaultFont", 10, "bold")
        title_label = ttk.Label(self, text="IO Settings", font=title_font)
        title_label.grid(row=0, column=0, sticky="nsew", padx=2, pady=2)
        row += 1

        separator = ttk.Separator(self, orient="horizontal")
        separator.grid(row=row, column=0, sticky="nsew", padx=2, pady=2)
        row += 1

        if not controller:
            warning("No controller provided")
        else:
            self.controller = controller
            controller.grid(row=row, column=0, sticky="nsew", padx=2, pady=2)
            row += 1

        row_layer = ttk.Frame(self)
        row_layer.grid(row=row, column=0, sticky="nsew", padx=2, pady=2)
        settings_button = ttk.Button(row_layer, text="Settings")
        settings_button.grid(row=0, column=0, sticky="nsew", padx=2, pady=2)
        open_button = ttk.Button(row_layer, text="Open")
        open_button.grid(row=0, column=1, sticky="nsew", padx=2, pady=2)
        open_button.config(command=self.open_io)
        row_layer.grid_columnconfigure(0, weight=1)
        row_layer.grid_columnconfigure(1, weight=1)
        row += 1

        self.open_btn = open_button
        self.grid_columnconfigure(0, weight=1)

    def open_io(self):
        if not self.controller:
            warning("No controller provided")
            return

        self.controller.open_io()
        self.open_btn.config(text="Close")
        self.open_btn.config(command=self.close_io)
        self.restart_check_io_timer()

    def close_io(self):
        self.stop_check_io_timer()
        if not self.controller:
            warning("No controller provided")
            return

        self.controller.close_io()
        self.open_btn.config(text="Open")
        self.open_btn.config(command=self.open_io)

    def __check_io(self):
        if self.timer.is_alive():
            self.timer.cancel()

        if not self.page or not self.controller:
            return

        data_items = self.controller.output_queue()
        if not data_items:
            self.restart_check_io_timer()
            return

        while data_items.qsize() > 0:
            data_item = data_items.get()
            self.page.output_data(data_item)

        self.restart_check_io_timer()

    def restart_check_io_timer(self):
        if self.timer and self.timer.is_alive():
            self.timer.cancel()

        self.timer = threading.Timer(self.__check_io_interval, self.__check_io)
        self.timer.daemon = True
        self.timer.start()

    def stop_check_io_timer(self):
        if self.timer and self.timer.is_alive():
            self.timer.cancel()

    def input_data(self, data):
        if not self.controller:
            return

        input_queue = self.controller.input_queue()
        if not input_queue:
            return

        input_queue.put(data)